//================================================
//  Company     : ICDREC
//  Project     : SG8
//  File name   : tmr3_cap_cmp.v
//  Author      : Nguyễn Việt
//  Date        : August 05th 2014
//  Version     : 
//-------------------------------------------------
// Modification History
// Date: 	By: 
// - 
//=================================================
`include "tmr3_define.h"
module tmr3_cap_cmp(
					//clock and reset
					gclk_tmr3,
					reset_n,
					//inputs
					tmr3_cap_ev,
					tcon,
					t3cnt,
					cmp,
					//outputs
					set_capif,
					set_cmpif,
					tmr3_cmp_out,
					cnt_en,
					tmr3_on
					);
	// clock and reset
	input 			gclk_tmr3;
	input 			reset_n;
	//inputs
	input 			tmr3_cap_ev;
	input 	[5:0] 	tcon;
	input 	[23:0] 	t3cnt;
	input 	[23:0] 	cmp;
	input			cnt_en;
	input			tmr3_on;
	//output
	output 			tmr3_cmp_out;
	output 			set_capif;
	output 			set_cmpif;
	//internal wires and registers
	reg 			sync_reg0;
	reg 			sync_reg1;
	reg 			detect_edge;
	reg 	[3:0] 	cap_pres;
	reg 			tmr3_cmp_out;
	reg 			reg0;
	reg				reg1;
	wire 			ev_en;
	wire 	[5:0] 	tcon;
	wire 			cap_cyc_en;
	wire 			cap_en;
	wire 			w1;
	wire 			w2;
	reg 			set_capif;
	wire 			cmp_en;
	wire 			out_en;
	wire 			setup_en;
	wire 			detect_setup_en;
//
//capture												
//
	//SYNC signal external
	always @(posedge gclk_tmr3) begin
			sync_reg0 <= `DELAY tmr3_cap_ev;
			sync_reg1 <= `DELAY sync_reg0;
			detect_edge <= `DELAY sync_reg1;
	end
	//
	assign ev_en = (tcon[4] == 1'b1) ? (sync_reg1 & (~detect_edge)) : (~sync_reg1 & detect_edge);
	//prescaler	
	assign cap_cyc_en = ev_en & tcon[5];
	assign cap_en = cap_cyc_en & (tcon[3]^tcon[2]);
	//
	always @(posedge gclk_tmr3) begin 
		if(reset_n == 1'b0)
			cap_pres[3:0] <= `DELAY 4'h0;
		else if(cap_en)
			cap_pres[3:0] <= `DELAY cap_pres[3:0] + 1'b1;
		else
			cap_pres[3:0] <= `DELAY cap_pres[3:0];
	end
	//
	assign w1 = cap_pres[0] & cap_pres[1];
	assign w2 = cap_pres[2] & cap_pres[3] & w1;
	//
	always @(*) begin
		case(tcon[3:2])
			 2'b00: set_capif = cap_cyc_en & ev_en;
			 2'b01: set_capif = cap_cyc_en & w1;
			 2'b10: set_capif = cap_cyc_en & w2;
			 default set_capif = 1'b0;
		endcase
	end
//
//	compare												
//
	assign cmp_en = ~tcon[5] & tcon[4];
	assign out_en = cmp_en & (t3cnt[23:0] == cmp[23:0]);
	assign setup_en = cmp_en & tmr3_on;
	//
	always @(posedge gclk_tmr3) begin
		reg1 <= `DELAY out_en;
	end
	assign set_cmpif = ~reg1 & out_en;
	//
	always @(posedge gclk_tmr3) begin
		reg0 <= `DELAY setup_en;
	end
	assign detect_setup_en = ~reg0 & setup_en;
	//
	always @(posedge gclk_tmr3) begin
		if(reset_n == 1'b0)
			tmr3_cmp_out <= `DELAY 1'b0;
		else
			if(tmr3_on == 1'b1)
				casez({detect_setup_en,out_en,tcon[3:2]})
					4'b1???: tmr3_cmp_out <= `DELAY ~tcon[3] & tcon[2];
					4'b0100: tmr3_cmp_out <= `DELAY 1'b1;
					4'b0101: tmr3_cmp_out <= `DELAY 1'b0;
					4'b0110: tmr3_cmp_out <= `DELAY ~tmr3_cmp_out;
					default tmr3_cmp_out <= `DELAY tmr3_cmp_out;
				endcase
			else
				tmr3_cmp_out <= `DELAY 1'b0;
	end
endmodule


		
